// Move.h
//
// Created By: Jeremy Butler
// Created On: 21-Mar-2011

#include <iostream>
#include <sstream>
#include <string>

#include "Move.h"
using namespace std;

Move::Move() : fromPiece(NULL),
	       fromLocation(-1,-1),
	       toPiece(NULL),
	       toLocation(-1,-1),
	       takenPiece(NULL){
  return;
}

Move::Move(const Piece & _fromPiece, int _fromRow, int _fromCol,
     const Piece * _toPiece, int _toRow, int _toCol,
     const Piece * _takenPiece) :
  fromPiece(_fromPiece.Clone()),
  fromLocation(_fromCol, _fromRow),
  toPiece((!_toPiece) ? _fromPiece.Clone() : _toPiece->Clone()),
  toLocation(_toCol, _toRow){

  if(_takenPiece)
    takenPiece = _takenPiece->Clone();
  else
    takenPiece = NULL;
  
  return;
}

Move::Move(const Move & other) :
  fromPiece((other.fromPiece != NULL) ? other.fromPiece->Clone() : NULL),
  fromLocation(other.fromLocation),
  toPiece((other.toPiece != NULL) ? other.toPiece->Clone() : NULL),
  toLocation(other.toLocation),
  takenPiece((other.takenPiece != NULL) ? other.takenPiece->Clone() : NULL){

    return;
}

Move::~Move(){
  Clear();
}

Move & Move::operator = (const Move & other){
  if(this != &other){
    fromPiece = (other.fromPiece != NULL) ? other.fromPiece->Clone() : NULL;
    fromLocation = other.fromLocation;
    toPiece = (other.toPiece != NULL) ? other.toPiece->Clone() : NULL;
    toLocation = other.toLocation;
    takenPiece = (other.takenPiece != NULL) ? other.takenPiece->Clone() : NULL;
  }
  return *this;
}

const Piece * Move::GetFromPiece() const{
  return fromPiece;
}

const Piece * Move::GetToPiece() const{
  return toPiece;
}

const Piece * Move::GetTakenPiece() const{
  return takenPiece;
}

const Location & Move::GetFromLocation() const{
  return fromLocation;
}

const Location & Move::GetToLocation() const{
  return toLocation;
}

string Move::ToString() const{
  stringstream str;
  str << "Before: ";
  if(fromPiece != NULL)
    str << fromPiece->ToString();
  else
    str << "Unitialized Piece";
  str << " at row: " << fromLocation.GetY() << ", column: " << fromLocation.GetX() << endl;
  str << "After: ";
  if(toPiece != NULL)
    str << toPiece->ToString();
  else
    str << "Unitialized Piece";
  str << " at row: " << toLocation.GetY() << ", column: " << toLocation.GetX();
  if (takenPiece != NULL){
    str << endl << takenPiece->ToString() + " taken";
  }

  return str.str();
}

void Move::Clear(){
  if(fromPiece != NULL)
    delete fromPiece;
  if(toPiece != NULL)
    delete toPiece;
  if(takenPiece != NULL)
    delete takenPiece;
}